(use-modules
 ;; SRFI 64 for unit testing facilities
 (srfi srfi-64)
 ;; utils - the code to be tested
 (utils test))


(test-begin "test-utils-test")

(test-group
 "approximately-equal?"
 ;; (value1 value2 epsilon)
 ;; simple numbers
 (test-assert "approximately-equal?-1"
   (approximately-equal? 1 1.001 0.002))
 (test-assert "approximately-equal?-2"
   (not (approximately-equal? 1 0.99 0.002)))
 (test-assert "approximately-equal?-3"
   (approximately-equal? 1 0.999 0.002))
 (test-assert "approximately-equal?-4"
   ;; Cannot specify as decimal numbers here, because of floating point
   ;; inprecision.
   (approximately-equal? 1 (/ 999 1000) (/ 1 1000))))

(test-group
 "vectors-approximately-equal?"
 ;; (v1 v2 epsilon compare-proc)
 ;; simple vectors
 (test-assert "vectors-approximately-equal?-1"
   (vectors-approximately-equal?
    #(1 -2     3 4.1 -5.001)
    #(1 -1.998 3 4.1 -5.001)
    #|epsilon|#
    0.003
    approximately-equal?))

 ;; Test if it also works for other things than numbers.
 (test-assert "vectors-approximately-equal?-2"
   (vectors-approximately-equal?
    #("a" "b" "cc" "a")
    #("" "ba" "acc" "a")
    "a"
    (lambda (s1 s2 epsilon)
      (or (string=? s1 s2)
          (string=? (string-append s1 epsilon) s2)
          (string=? (string-append epsilon s1) s2)
          (string=? (string-append epsilon s2) s1)
          (string=? (string-append s2 epsilon) s1))))))

(test-group
 "lists-of-vectors-approximately-equal?"
 ;; (l1 l2 epsilon compare-proc)
 ;; list of vectors
 (test-assert "lists-of-vectors-approximately-equal?-1"
   (not
    (lists-of-vectors-approximately-equal?
     (list #(1 2 3) #(1.1 1.9 3))
     (list #(1 2 3) #(1.1 1.9 3.15))
     0.1
     (lambda (le1 le2 epsilon)
       (vectors-approximately-equal? le1 le2 epsilon approximately-equal?)))))

 (test-assert "lists-of-vectors-approximately-equal?-2"
   (lists-of-vectors-approximately-equal?
    (list (vector 1 2 3)
          (vector 1 2 3))
    (list (vector 1 2 3)
          (vector (/ 11 10) (/ 19 10) (/ 31 10)))
    (/ 1 10)
    (lambda (le1 le2 epsilon)
      (vectors-approximately-equal? le1 le2 epsilon approximately-equal?)))))

(test-group
 "vector-set"
 ;; Test if the update works.
 (test-equal "vector-set-1"
   (vector 1 1 10 1)
   (vector-set (vector 1 1 1 1) 2 10))

 ;; Test if the original vector is unchanged.
 (test-equal "vector-set-2"
   (vector 1 1 1 1)
   (let ([original-vector (vector 1 1 1 1)])
     (vector-set original-vector 2 10)
     original-vector)))

(test-end "test-utils-test")
